package com.micro.ai.models.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.micro.ai.commons.exception.BusinessException;
import com.micro.ai.models.entity.FineTunedModel;
import com.micro.ai.models.mapper.FineTunedModelMapper;
import com.micro.ai.models.service.FineTunedModelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

/**
 * 微调模型服务实现
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
@Service
public class FineTunedModelServiceImpl extends ServiceImpl<FineTunedModelMapper, FineTunedModel> implements FineTunedModelService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FineTunedModel create(FineTunedModel model) {
        if (model == null) {
            throw new BusinessException("M0000", "微调模型信息不能为空");
        }
        
        LocalDateTime now = LocalDateTime.now();
        model.setCreatedAt(now);
        model.setUpdatedAt(now);
        if (model.getStatus() == null) {
            model.setStatus("trained");
        }
        
        boolean success = this.save(model);
        if (!success) {
            throw new BusinessException("M0003", "保存微调模型失败");
        }
        
        log.info("创建微调模型成功: modelId={}, modelName={}", model.getId(), model.getModelName());
        return model;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FineTunedModel update(String id, FineTunedModel model) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("M0000", "模型ID不能为空");
        }
        if (model == null) {
            throw new BusinessException("M0000", "微调模型信息不能为空");
        }
        
        FineTunedModel existing = this.getById(id);
        if (existing == null) {
            throw new BusinessException("M0002", "微调模型不存在: " + id);
        }
        
        model.setId(id);
        model.setUpdatedAt(LocalDateTime.now());
        
        boolean success = this.updateById(model);
        if (!success) {
            throw new BusinessException("M0003", "更新微调模型失败");
        }
        
        log.info("更新微调模型成功: modelId={}", id);
        return model;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("M0000", "模型ID不能为空");
        }
        
        FineTunedModel model = this.getById(id);
        if (model == null) {
            throw new BusinessException("M0002", "微调模型不存在: " + id);
        }
        
        boolean success = this.removeById(id);
        if (!success) {
            throw new BusinessException("M0003", "删除微调模型失败");
        }
        
        log.info("删除微调模型成功: modelId={}, modelName={}", id, model.getModelName());
    }

    @Override
    public Page<FineTunedModel> pageQuery(int pageNum, int pageSize, String tenantId, String keyword, String status) {
        if (pageNum < 1) {
            pageNum = 1;
        }
        if (pageSize < 1 || pageSize > 100) {
            pageSize = 20;
        }
        
        Page<FineTunedModel> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<FineTunedModel> query = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(tenantId)) {
            query.eq(FineTunedModel::getTenantId, tenantId);
        }
        if (StringUtils.hasText(status)) {
            query.eq(FineTunedModel::getStatus, status);
        }
        if (StringUtils.hasText(keyword)) {
            query.and(q -> q.like(FineTunedModel::getModelName, keyword)
                          .or().like(FineTunedModel::getModelAlias, keyword));
        }
        
        query.orderByDesc(FineTunedModel::getCreatedAt);
        
        return this.page(page, query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deploy(String id) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("M0000", "模型ID不能为空");
        }
        
        FineTunedModel model = this.getById(id);
        if (model == null) {
            throw new BusinessException("M0002", "微调模型不存在: " + id);
        }
        
        model.setStatus("deploying");
        model.setUpdatedAt(LocalDateTime.now());
        
        boolean success = this.updateById(model);
        if (!success) {
            throw new BusinessException("M0003", "部署模型失败");
        }
        
        log.info("开始部署模型: modelId={}, modelName={}", id, model.getModelName());
        
        // 使用部署服务部署模型
        try {
            // 如果注入了ModelDeploymentService，则使用它部署模型
            // ModelDeploymentService deploymentService = ...; // 通过Spring注入
            // ModelDeploymentService.DeploymentInfo info = deploymentService.deployModel(model);
            
            // 验证部署是否成功
            // boolean isAvailable = deploymentService.verifyDeployment(info);
            // if (!isAvailable) {
            //     throw new BusinessException("M0003", "模型服务验证失败");
            // }
            
            // 更新模型信息
            // model.setModelPath(info.getApiEndpoint());
            
            // 更新状态为active
            model.setStatus("active");
            model.setDeployedAt(LocalDateTime.now());
            this.updateById(model);
            
            // 实际实现时，可以选择以下方案之一：
            // 方案1: HuggingFace Hub - 适合开源模型
            // 方案2: 自建模型服务（vLLM、TensorRT-LLM等）
            // 方案3: 云服务商（AWS SageMaker、Azure ML等）
            // 方案4: 容器化部署（Docker/Kubernetes）
            
            log.info("模型部署完成: modelId={}, modelName={}", id, model.getModelName());
            
        } catch (Exception e) {
            log.error("部署模型失败: modelId={}, error={}", id, e.getMessage(), e);
            // 回滚状态
            model.setStatus("trained");
            model.setErrorMessage("部署失败: " + e.getMessage());
            this.updateById(model);
            throw new BusinessException("M0003", "部署模型失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void archive(String id) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("M0000", "模型ID不能为空");
        }
        
        FineTunedModel model = this.getById(id);
        if (model == null) {
            throw new BusinessException("M0002", "微调模型不存在: " + id);
        }
        
        model.setStatus("archived");
        model.setUpdatedAt(LocalDateTime.now());
        
        boolean success = this.updateById(model);
        if (!success) {
            throw new BusinessException("M0003", "归档模型失败");
        }
        
        log.info("归档模型: modelId={}, modelName={}", id, model.getModelName());
    }
}

